
package com.rt.schedulenew.utils.pkgenerator;
import java.util.Enumeration;
import java.net.SocketException;
import java.net.NetworkInterface;
import java.lang.management.RuntimeMXBean;
import java.lang.management.ManagementFactory;
public class PKGeneratorCluster
{
    private static final long twepoch = 12888349746579L;
    private static final long workerIdBits = 5L;
    private static final long datacenterIdBits = 5L;
    private static final long sequenceBits = 12L;
    private static final long workerIdShift = 12L;
    private static final long datacenterIdShift = 17L;
    private static final long timestampLeftShift = 22L;
    private static final long sequenceMask = 4095L;
    private static long lastTimestamp;
    private long sequence;
    private long workerId;
    private static long workerMask;
    private long processId;
    private static long processMask;
    private static PKGeneratorCluster generatorCluster;
    
    public static synchronized long nextPk() {
        return PKGeneratorCluster.generatorCluster.getNextId();
    }
    
    public static synchronized String nextPkStr() {
        return Long.toString(PKGeneratorCluster.generatorCluster.getNextId());
    }
    
    private PKGeneratorCluster() {
        this.sequence = 0L;
        this.workerId = 1L;
        this.processId = 1L;
        this.workerId = this.getMachineNum();
        final RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
        this.processId = Long.valueOf(runtimeMXBean.getName().split("@")[0]);
        this.workerId &= PKGeneratorCluster.workerMask;
        this.processId &= PKGeneratorCluster.processMask;
    }
    
    public synchronized long getNextId() {
        long timestamp = this.timeGen();
        if (timestamp < PKGeneratorCluster.lastTimestamp) {
            try {
                throw new Exception("Clock moved backwards.  Refusing to generate id for " + (PKGeneratorCluster.lastTimestamp - timestamp) + " milliseconds");
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (PKGeneratorCluster.lastTimestamp == timestamp) {
            this.sequence = (this.sequence + 1L & 0xFFFL);
            if (this.sequence == 0L) {
                timestamp = this.tilNextMillis(PKGeneratorCluster.lastTimestamp);
            }
        }
        else {
            this.sequence = 0L;
        }
        PKGeneratorCluster.lastTimestamp = timestamp;
        final long nextId = timestamp - 12888349746579L << 22 | this.processId << 17 | this.workerId << 12 | this.sequence;
        return nextId;
    }
    
    private long tilNextMillis(final long lastTimestamp) {
        long timestamp;
        for (timestamp = this.timeGen(); timestamp <= lastTimestamp; timestamp = this.timeGen()) {}
        return timestamp;
    }
    
    private long timeGen() {
        return System.currentTimeMillis();
    }
    
    private long getMachineNum() {
        final StringBuilder sb = new StringBuilder();
        Enumeration<NetworkInterface> e = null;
        try {
            e = NetworkInterface.getNetworkInterfaces();
        }
        catch (SocketException e2) {
            e2.printStackTrace();
        }
        while (e.hasMoreElements()) {
            final NetworkInterface ni = e.nextElement();
            sb.append(ni.toString());
        }
        final long machinePiece = sb.toString().hashCode();
        return machinePiece;
    }
    
    static {
        PKGeneratorCluster.lastTimestamp = -1L;
        PKGeneratorCluster.workerMask = 31L;
        PKGeneratorCluster.processMask = 31L;
        PKGeneratorCluster.generatorCluster = null;
        PKGeneratorCluster.generatorCluster = new PKGeneratorCluster();
    }
}
